home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / objcissu.lha / loadModules < prev    next >
Text File  |  1993-03-01  |  8KB  |  304 lines

  1. Newsgroups: comp.sys.next.programmer
  2. From: mauriti@cs.tu-berlin.de (Frank Hartlep)
  3. Subject: Re: Loading classes at run-time: How?
  4. Organization: Technical University of Berlin, Germany
  5. Date: Mon, 21 Sep 1992 13:14:22 GMT
  6.  
  7. Here's the promised code for loading/unloading classes in a
  8. random order. This means that sets of classes loaded
  9. with objc_loadModules() do not need to be unloaded in reverse
  10. order - unload them as you like. Just take care not to unload
  11. a class if subclasses are still around. Two notes on loading:
  12. when loading a set of classes the name of a class must
  13. precede the names of its subclasses in the file list,
  14. otherwise the load will fail; objc_loadModules will also load
  15. non-class object files.
  16.  
  17. The C code is a snippet of my original code. I hope I haven't
  18. introduced any errors (I haven't tested it, but it compiled well).
  19. LoadModules() loads all the object or archive files in alphabetic
  20. order in a directory of your choice. It just uses plain old
  21. objc_loadModules. UnloadClasses() unloads the class set associated
  22. with a given mach header. If you're wondering why I'm giving you
  23. assembler code: The code is a patched version of objc_unloadModules().
  24. I only changed two things: 1. Instead of obtaining a mach header by
  25. calling rld_current_header it now uses the one passed as argument,
  26. and 2. it doesn't call rld_unload anymore before finishing.
  27. After trying many things this is still the best solution
  28. I could think of.
  29. I've tried the code quite a few times, and so far no errors
  30. showed up. What I don't know is if the code handles categories
  31. correctly. If you find any bugs, please let me know.
  32. Btw, NextAnswers misc.567 was of great help. Read it, if you haven't.
  33.  
  34.  
  35. Frank
  36.  
  37.  
  38. __________
  39.  
  40.  
  41.  
  42. #include <libc.h>
  43. #include <objc/objc-load.h>
  44. #include <cthreads.h>
  45. #include <rld.h>
  46. #include <stdio.h>
  47. #include <string.h>
  48. #include <sys/dir.h>
  49. #include <sys/param.h>
  50.  
  51.  
  52. extern int UnloadClasses (
  53.         struct mach_header *, NXStream *, void (*) (Class, Category));
  54.  
  55.  
  56. static void ToSeeIsToBelieve(
  57.         Class           LoadedClass,
  58.         Category        LoadedCategory)
  59. {
  60.         if (LoadedCategory != NULL)
  61.                 printf (
  62.                         "class = %s, category = %s\n",
  63.                         LoadedCategory->class_name,
  64.                         LoadedCategory->category_name);
  65.         else
  66.                 printf ("class = %s\n", LoadedClass->name);
  67.         return;
  68. }
  69.  
  70.  
  71. static int IsObjectOrArchiveFile (
  72.         struct direct   *File)
  73. {
  74.         char            *Extension;
  75.  
  76.         Extension = rindex (File->d_name, '.');
  77.         return Extension != NULL && (! strcmp (Extension, ".o") ||
  78.                                      ! strcmp (Extension, ".a"));
  79. }
  80.  
  81.  
  82. int LoadModules (
  83.         char            *WhereToLoadFrom,
  84.         struct mach_header      **MachHeader,
  85.         vm_size_t       *RegionSize)
  86. {
  87.         NXStream        *ErrorStream;
  88.         char            *OutputFile = "rld.gdb";
  89.         boolean_t       Shared;
  90.         char            Cwd [MAXPATHLEN + 1],
  91.                         **LoadFiles;
  92.         int             IsBadLoad, Files, i;
  93.         port_t          ObjectName;
  94.         struct direct   **ToBeLoaded;
  95.         vm_address_t    Region;
  96.         vm_inherit_t    Inheritance;
  97.         vm_offset_t     Offset;
  98.         vm_prot_t       Protection, MaxProtection;
  99.  
  100.         ErrorStream = NXOpenFile (fileno (stderr), NX_WRITEONLY);
  101.         getwd (Cwd);
  102.         if (chdir (WhereToLoadFrom) == -1) {
  103.                 NXPrintf (ErrorStream, "no such directory\n");
  104.                 goto Error;
  105.         }
  106.         LoadFiles = (char **) malloc (1);
  107.         Files = scandir (".", &ToBeLoaded, IsObjectOrArchiveFile, alphasort);
  108.         for (i = 0; i < Files; i ++) {
  109.                 LoadFiles = (char **) realloc (
  110.                                         LoadFiles, (i + 2) * sizeof (char *));
  111.                 LoadFiles [i] = ToBeLoaded [i]->d_name;
  112.         }
  113.         LoadFiles [i] = NULL;
  114.         printf ("Loading ...\n");
  115.         IsBadLoad = objc_loadModules (
  116.                         LoadFiles, ErrorStream, ToSeeIsToBelieve,
  117.                         MachHeader,OutputFile);
  118.         for (i = 0; i < Files; i ++)
  119.                 free (ToBeLoaded [i]);
  120.         free (ToBeLoaded);
  121.         chdir (Cwd);
  122.         if (IsBadLoad)
  123.                 goto Error;
  124.         Region = (vm_address_t) *MachHeader;
  125.         vm_region (
  126.                 task_self (), &Region, RegionSize,
  127.                 &Protection, &MaxProtection, &Inheritance,
  128.                 &Shared, &ObjectName, &Offset);
  129.         if (! rld_unload_all (ErrorStream, 0))
  130.                 goto Error;
  131.         NXClose (ErrorStream);
  132.         return 0;
  133. Error:
  134.         NXClose (ErrorStream);
  135.         return -1;
  136. }
  137.  
  138.  
  139. void UnloadClassesAndFree (
  140.         struct mach_header      *MachHeader,
  141.         vm_size_t       RegionSize)
  142. {
  143.         printf ("Unloading ...\n");
  144.         UnloadClasses (MachHeader, NULL, ToSeeIsToBelieve);
  145.         vm_deallocate (
  146.                 task_self (),(vm_address_t) MachHeader,RegionSize);
  147.         return;
  148. }
  149.  
  150.  
  151. __________
  152.  
  153.  
  154.  
  155. #NO_APP
  156.  
  157. .set _send_unload_message_to_category,0x05033c76
  158. .set _send_unload_message_to_class,0x05033cbe
  159. .set __objc_remove_category,0x050322cc
  160. .set __sel_unloadSelectors,0x5032534
  161.  
  162. .cstring
  163. LC0:
  164.         .ascii  "__OBJC\0"
  165. LC1:
  166.         .ascii  "__module_info\0"
  167. LC2:
  168.         .ascii  "__selector_strs\0"
  169.  
  170. .text
  171.         .even
  172. .globl _UnloadClasses
  173. _UnloadClasses:
  174.         linkw a6,#-8
  175.         moveml d2/d3/d4/d5/d6/d7/a2/a3/a4,sp@-
  176.         movel a6@(12),a4
  177.         movel a6@(16),a3
  178.         movel a6@(8),d5
  179.         pea a6@(-4)
  180.         pea LC1:l
  181.         pea LC0:l
  182.         movel d5,sp@-
  183.         jsr _getsectdatafromheader
  184.         movel d0,a2
  185.         movel a2,d7
  186.         movel a6@(-4),d6
  187.         addw #16,sp
  188.         tstl a2
  189.         jeq L2
  190.         tstl d6
  191.         jeq L2
  192.         clrl d4
  193. L10:    movel a2@(12),a0
  194.         movew a0@(8),d4
  195.         movel d4,d2
  196.         clrl d3
  197.         bras L3
  198. L5:     tstl a3
  199.         beqs L4
  200.         movel a2@(12),a0
  201.         movel a0@(12:b,d2:l:4),sp@-
  202.         movel a0@(12:b,d2:l:4),a0
  203.         movel a0@(4),sp@-
  204.         jsr _objc_getClass
  205.         addqw #4,sp
  206.         movel d0,sp@-
  207.         jsr a3@
  208.         addqw #8,sp
  209. L4:     movel a2@(12),a0
  210.         movel a0@(12:b,d2:l:4),sp@-
  211.         jsr _send_unload_message_to_category
  212.         addqw #4,sp
  213.         addql #1,d2
  214. L3:     movel a2@(12),a0
  215.         movew a0@(8),d3
  216.         movew a0@(10),d4
  217.         movel d3,d0
  218.         addl d4,d0
  219.         cmpl d2,d0
  220.         bgts L5
  221.         clrl d2
  222.         clrl d3
  223.         bras L6
  224. L8:     tstl a3
  225.         beqs L7
  226.         clrl sp@-
  227.         movel a2@(12),a0
  228.         movel a0@(12:b,d2:l:4),sp@-
  229.         jsr a3@
  230.         addqw #8,sp
  231. L7:     movel a2@(12),a0
  232.         movel a0@(12:b,d2:l:4),sp@-
  233.         jsr _send_unload_message_to_class
  234.         addqw #4,sp
  235.         addql #1,d2
  236. L6:     movel a2@(12),a0
  237.         movew a0@(8),d3
  238.         cmpl d2,d3
  239.         bgts L8
  240.         movel a6@(-4),d0
  241.         subl a2@(4),d0
  242.         movel d0,a6@(-4)
  243.         beqs L9
  244.         addl a2@(4),a2
  245. L9:     tstl a6@(-4)
  246.         jne L10
  247.         movel d7,a2
  248.         movel d6,a6@(-4)
  249. L16:    movel a2@(12),a0
  250.         clrl d0
  251.         movew a0@(8),d0
  252.         movel d0,d2
  253.         clrl d4
  254.         clrl d3
  255.         bras L11
  256. L12:    movel a2@(12),a0
  257.         movel a0@(12:b,d2:l:4),sp@-
  258.         jsr __objc_remove_category
  259.         addqw #4,sp
  260.         addql #1,d2
  261. L11:    movel a2@(12),a0
  262.         movew a0@(8),d4
  263.         movew a0@(10),d3
  264.         movel d4,d0
  265.         addl d3,d0
  266.         cmpl d2,d0
  267.         bgts L12
  268.         clrl d2
  269.         clrl d3
  270.         bras L13
  271. L14:    movel a2@(12),a0
  272.         movel a0@(12:b,d2:l:4),sp@-
  273.         jsr _objc_getClasses
  274.         movel d0,sp@-
  275.         jsr _NXHashRemove
  276.         addqw #8,sp
  277.         addql #1,d2
  278. L13:    movel a2@(12),a0
  279.         movew a0@(8),d3
  280.         cmpl d2,d3
  281.         bgts L14
  282.         movel a6@(-4),d0
  283.         subl a2@(4),d0
  284.         movel d0,a6@(-4)
  285.         beqs L15
  286.         addl a2@(4),a2
  287. L15:    tstl a6@(-4)
  288.         bnes L16
  289.         pea a6@(-8)
  290.         pea LC2:l
  291.         pea LC0:l
  292.         movel d5,sp@-
  293.         jsr _getsectdatafromheader
  294.         movel d0,d1
  295.         addl a6@(-8),d1
  296.         movel d1,sp@-
  297.         movel d0,sp@-
  298.         jsr __sel_unloadSelectors
  299.         clrl d0
  300. L2:     moveml a6@(-44),d2/d3/d4/d5/d6/d7/a2/a3/a4
  301.         unlk a6
  302.         rts
  303.  
  304.